﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//Csharp客户端代码
class CsharpClientCodeCreater
{
    public static void CreateBaseCode(string outputPath)
    {
        if (!Directory.Exists(outputPath))
            Directory.CreateDirectory(outputPath);

        string strFilePath = outputPath + "/ICfg.cs";

        StreamWriter sw = new StreamWriter(strFilePath, false, Encoding.UTF8);
        StringBuilder strBuilder = new StringBuilder();
        strBuilder.AppendLine("using System;")
                    .AppendLine("namespace GameCFG")
                    .AppendLine("{");

        strBuilder.AppendFormat("\tpublic interface {0}\r\n", "ICfg");
        strBuilder.AppendLine("\t{");

        strBuilder.AppendLine("\t\tvoid DeSerialize(ByteBuffer buff);")
                    .AppendLine();

        strBuilder.AppendLine("\t}")
                    .AppendLine("}");

        sw.Write(strBuilder);
        sw.Flush();
        sw.Close();
    }

    public static void CreateCode(ExcelFile file, string outputPath)
    {
        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }
        string strFilePath = outputPath + "/Data_" + file.FileName + ".cs";
        if (File.Exists(strFilePath) == true)
        {
            //return;
        }

        StreamWriter sw = new StreamWriter(strFilePath, false, Encoding.UTF8);
        StringBuilder strBuilder = new StringBuilder();


        strBuilder.AppendLine("/*工具自动生成代码请勿修改");
        strBuilder.AppendLine(" 创建时间" + DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss" + "*/"));

        strBuilder.AppendLine("using System;")
                    .AppendLine("namespace GameCFG")
                    .AppendLine("{");

        strBuilder.AppendFormat("\tpublic class Data_{0}:ICfg\r\n", file.FileName);
        strBuilder.AppendLine("\t{");

        strBuilder.AppendLine();

        var e = file.TypeDic.GetEnumerator();
        while (e.MoveNext())
        {
            string type = e.Current.Value;
            string exportType = file.ExportTypeDic[e.Current.Key];
            string propName = file.PropNameDic[e.Current.Key];
            string notes = file.NotesDic[e.Current.Key];
            if (string.IsNullOrEmpty(exportType) || exportType == "CLIENT" || exportType == "ALL")
            {
                string t = CodeUtil.GetDataType(CodeUtil.Csharp, type);

                strBuilder.AppendLine(string.Format("\t\t//{0}", notes));
                strBuilder.AppendLine(string.Format("\t\tprivate {0} m_{1};", t, propName));
                strBuilder.AppendLine(string.Format("\t\tpublic {0} " + "{1}" + "{{ get " + "{{ return m_" + "{2}" + "; }}" + " }}", t, propName, propName));

                strBuilder.AppendLine();
            }
        }

        strBuilder.AppendLine("\t\tpublic void DeSerialize(ByteBuffer buff)")
                    .AppendLine("\t\t{");

        e = file.TypeDic.GetEnumerator();
        while (e.MoveNext())
        {
            string type = e.Current.Value;
            string exportType = file.ExportTypeDic[e.Current.Key];
            string propName = file.PropNameDic[e.Current.Key];
            if (string.IsNullOrEmpty(exportType) || exportType == "CLIENT" || exportType == "ALL")
            {
                string t = CodeUtil.GetDataType(CodeUtil.Csharp, type);
                string f = CodeUtil.GetCsharpReadFunction(type);
                strBuilder.AppendLine(string.Format("\t\t\tm_{0} = buff.{1}();", propName, f));
            }
        }

        strBuilder.AppendLine("\t\t}")
                    .AppendLine();

        strBuilder.AppendLine("\t}")
                    .AppendLine("}");

        sw.Write(strBuilder);
        sw.Flush();
        sw.Close();

        CreateManagerCode(file, outputPath);
    }

    private static void CreateManagerCode(ExcelFile file, string outputPath)
    {
        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }
        string strFilePath = outputPath + "/DataMgr_" + file.FileName + ".cs";
        if (File.Exists(strFilePath) == true)
        {
            //return;
        }

        StreamWriter sw = new StreamWriter(strFilePath, false, Encoding.UTF8);
        StringBuilder strBuilder = new StringBuilder();

        string keyProp = file.PropNameDic[0];

        string keyType = CodeUtil.GetDataType(CodeUtil.Csharp, file.TypeDic[0]);

        strBuilder.AppendLine("/*工具自动生成代码请勿修改");
        strBuilder.AppendLine(" 创建时间" + DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss" + "*/"));

        strBuilder.AppendLine("using System;")
                    .AppendLine("using System.Collections.Generic;")
                    .AppendLine("namespace GameCFG")
                    .AppendLine("{");

        strBuilder.AppendFormat("\tpublic class DataMgr_{0}:ICfg\r\n", file.FileName);
        strBuilder.AppendLine("\t{");

        strBuilder.AppendLine(string.Format("\t\tpublic Dictionary<{0},Data_{1}> Data "+"{{get"+"{{return m_data;"+"}}"+"}}", keyType, file.FileName));

        strBuilder.AppendLine("\t\tpublic void DeSerialize(ByteBuffer buff)")
                    .AppendLine("\t\t{");

        strBuilder.AppendLine("\t\t\tInt16 count = buff.ReadInt16();");

        strBuilder.AppendLine("\t\t\tfor(int i = 0; i < count; i++)");
        strBuilder.AppendLine("\t\t\t{");
        strBuilder.AppendLine(string.Format("\t\t\t\tData_{0} data = new Data_{1}();",file.FileName, file.FileName));
        strBuilder.AppendLine("\t\t\t\tdata.DeSerialize(buff);");
        strBuilder.AppendLine(string.Format("\t\t\t\tm_data.Add(data.{0},data);", keyProp));
        strBuilder.AppendLine("\t\t\t}");

        strBuilder.AppendLine("\t\t}")
                    .AppendLine();


        strBuilder.AppendLine(string.Format("\t\tpublic static DataMgr_{0} Singleton", file.FileName));//{get{}}
        strBuilder.AppendLine("\t\t{");
        strBuilder.AppendLine("\t\t\tget{");
        strBuilder.AppendLine("\t\t\t\tif(m_singleton == null){");
        strBuilder.AppendLine(string.Format("\t\t\t\t\t m_singleton = new DataMgr_{0}();", file.FileName));

        strBuilder.AppendLine(string.Format("\t\t\t\t\t DataLoader.Load(m_singleton,\"{0}\");", file.FileName));

        strBuilder.AppendLine("\t\t\t\t}");

        strBuilder.AppendLine("\t\t\t\t return m_singleton;");

        strBuilder.AppendLine("\t\t\t}");
        strBuilder.AppendLine("\t\t}");

        strBuilder.AppendLine("\t\tprivate bool m_initState = false;");
        strBuilder.AppendLine(string.Format("\t\tprivate Dictionary<{0},Data_{1}> m_data = new Dictionary<{2},Data_{3}>();", keyType, file.FileName, keyType, file.FileName));
        strBuilder.AppendLine(string.Format("\t\tprivate static DataMgr_{0} m_singleton;", file.FileName));

        strBuilder.AppendLine("\t}")
                    .AppendLine("}");

        sw.Write(strBuilder);
        sw.Flush();
        sw.Close();
    }

}
